/*
 * serial.c
 *
 *  Created on: Oct 8, 2011
 *  Author: Mario H. Voorsluys
 *	email: forcaeluz@gmail.com
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, visit:
 * http://www.gnu.org/copyleft/gpl.html
 */

#include "serial.h"

void serial_init(){
	int ubrr_value = (F_CPU/(16*BAUD))-1;
	UCSRA = 0x00;
	//Frame size: 8 bits.
	UCSRC = (1<<URSEL)|(1 << UCSZ0) | (1 << UCSZ1);
	//Enable transmitter, receiver, receive complete interrupt
	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<< RXCIE);
	// Baud
	UBRRH = ubrr_value >> 8;
	UBRRL = ubrr_value;
	input_buffer.head = 0;
	input_buffer.tail = 0;
}

void serial_writte(unsigned char* data, int length){
	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<< RXCIE);
	for(int i=0; i < length; i++){
		while(!(UCSRA & (1 << UDRE)));
		UDR = data[i];
	}
}

int serial_read(){
	if(input_buffer.head == input_buffer.tail){
		return -1;
	}else{
		unsigned char c = (unsigned char)input_buffer.buffer[input_buffer.tail];
		input_buffer.tail = (input_buffer.tail+1)%BUFFERSIZE;
		return c;
	}
}

void flush_serial(){
	input_buffer.head = input_buffer.tail;
}

ISR(USART_RXC_vect){
	unsigned char c = UDR;
	int i = (unsigned int)((input_buffer.head + 1) % BUFFERSIZE);

	if (i != input_buffer.tail) {
		input_buffer.buffer[input_buffer.head] = c;
		input_buffer.head = i;
	}
}
